#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#define SIZE 1024
void Usage(std::string proc)
{
    std::cout << "\n\rUsage:" << proc << " serverip serverport" << std::endl;
}
// client serverip serverport
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }
    uint16_t serverport = std::stoi(argv[2]);
    std::string serverip = argv[1];

    // 2.准备数据
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server)); // 初始化结构体
    server.sin_family = AF_INET;
    server.sin_port = htons(serverport);
    inet_pton(AF_INET, serverip.c_str(), &server.sin_addr);
    // 3.OS自动绑定在第一次连接成功时
    // 4.发起连接
    while (true)
    {
        // 1.创建套接字
        int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
        if (sock_fd < 0)
        {
            return -1;
        }
        int cnt = 5;
        bool isconnect = false;
        do
        {
            ssize_t c = connect(sock_fd, (sockaddr *)&server, sizeof(server));
            if (c<0)
            {
                cnt--;
                isconnect = true;
                std::cout << "Is connect!! time: " << cnt << std::endl;
                sleep(2);
            }
            else
            {
                break;
            }
        } while (cnt && isconnect);
        if (cnt == 0)
        {
            std::cout << "user offline!!" << std::endl;
            break;
        }
        // 走到这里连接成功
        // 1.写
        std::cout << "Please enter@ " << std::endl;
        std::string line;
        std::getline(std::cin, line);
        ssize_t w = write(sock_fd, line.c_str(), line.size());
        if(w<0)
        {
            std::cout<<"Write fail!!"<<std::endl;
        }
    
        // 2.读
        char buffer[SIZE];
        ssize_t r = read(sock_fd, buffer, sizeof(buffer));
        if (r > 0)
        {
            buffer[r] = '\0';
            std::cout << buffer << std::endl;
        }
        close(sock_fd);
    }
    return 0;
}